package com.winbomb.kingcard.base;

import java.util.HashSet;
import java.util.Set;

import com.winbomb.kingcard.ICard;
import com.winbomb.kingcard.Suit;

public class Card implements ICard {

	public static final int UNDER_ATTACK = 1; // 是否遭受进攻卡片的攻击
	public static final int IS_DEFEATED = 1 << 1; // 是否是已经战败的卡片
	public static final int IS_COVERED = 1 << 2; // 是否是暗牌(即尚未翻开的牌)
	public static final int IS_ATK_CARD = 1 << 3; // 是否是当前的进攻卡片
	public static final int IS_ATK_TARGET = 1 << 4; // 是否是进攻的对象
	public static final int IS_UNOPEN_CARD = 1 << 5; // 是否是暗牌(尚未知道身份的牌)
	public static final int IS_GENERAL = 1 << 6; // 是否是叫阵的主将
	public static final int IS_FIRST_CHOICE = 1 << 7; // 是否是首选攻击对象
	public static final int IS_RECOMMENDED = 1 << 8; // 是否是推荐攻击对象
	public static final int IS_CAPTIVE = 1 << 9; // 是否是选择俘虏的

	public static final String SKILL_ROW_KILLER = "Skill Row killer";
	public static final String SKILL_EMPTY_CITY = "Skill Empty City";
	public static final String SKILL_CHEER_UP = "Skill Cheer up";

	/** 牌的点数 */
	private int point;

	/** 牌的花色 */
	private Suit suit;

	/** 是否被选中 */
	private boolean isSelected;

	/** 是否盖上 */
	private boolean isCovered;

	/** 牌的标志 */
	private int cardFlag;

	/** 牌的技能 */
	private Set<String> skillSet = new HashSet<String>();

	/** 花色和点数名称的定义 */
	private static final String[] suitName = new String[] { "黑桃", "红桃", "梅花", "方片" };
	private static final String[] pointName = new String[] { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J",
			"Q", "K" };
	private static final int[] POINT_BASE = new int[] { 900, 1000, 100, 200, 300, 400, 500, 600, 700, 800, 1100, 1200,
			1300, 1400, 1500 };

	public Card(int point, Suit suit) {
		this.point = point;
		this.suit = suit;
		this.isSelected = false;
		this.isCovered = false;
		this.cardFlag = 0;
	}

	@Override
	public String toString() {
		if (isRedJoker()) {
			return "大王";
		}

		if (isBlackJoker()) {
			return "小王";
		}

		return suitName[suit.ordinal()] + pointName[point - 1];

	}

	@Override
	public int getPoint() {
		if (point >= 1 && point <= 15) {
			return point;
		}

		return 0;
	}

	@Override
	public Suit getSuit() {
		return suit;
	}

	@Override
	public boolean isBlackJoker() {
		return (point == 14 && suit == Suit.BLACK);
	}

	@Override
	public boolean isRedJoker() {
		return (point == 15 && suit == Suit.RED);
	}

	/**
	 * 牌的排列顺序按照: 王->将->士->兵 , 即:
	 * 
	 * 大王/小王/K/Q/J/2/A/10/9...
	 * 
	 * 花色按照桃杏梅方顺序
	 * 
	 */
	@Override
	public int getOrdinal() {

		int base = POINT_BASE[point - 1];
		if (suit == Suit.DIAMOND) {
			base += 0;
		} else if (suit == Suit.CLUB) {
			base += 10;
		} else if (suit == Suit.HEART) {
			base += 20;
		} else if (suit == Suit.SPADE) {
			base += 30;
		}

		return base;
	}

	@Override
	public boolean isSelected() {
		return isSelected;
	}

	@Override
	public void setSelected(boolean isSelected) {
		this.isSelected = isSelected;
	}

	@Override
	public boolean isCovered() {
		return isCovered;
	}

	@Override
	public void setCovered(boolean isCovered) {
		this.isCovered = isCovered;
	}

	@Override
	public void clearFlag(int flag) {
		if ((cardFlag & flag) != 0) {
			cardFlag = cardFlag ^ flag;
		}
	}

	@Override
	public void clearAllFlags() {
		cardFlag = cardFlag & 0;
		isSelected = false;
		isCovered = false;
	}

	@Override
	public void setFlag(int flag) {
		cardFlag = cardFlag | flag;
	}

	@Override
	public boolean testFlag(int flag) {
		return ((cardFlag & flag) != 0);
	}

	@Override
	public void addSkill(String skillName) {
		skillSet.add(skillName);
	}

	@Override
	public boolean hasSkill(String skillName) {
		return skillSet.contains(skillName);
	}

	@Override
	public void removeSkill(String skillName) {
		if (skillSet.contains(skillName)) {
			skillSet.remove(skillName);
		}
	}

	@Override
	public void clearAllSkills() {
		skillSet.clear();
	}

	@Override
	public boolean canBeat(ICard tgCard) {

		// 如果本方是王或者A或者2, 可以克制任何不同颜色的牌
		if (this.isRedJoker() || this.isBlackJoker() || this.point == 1 || this.point == 2) {
			return !suit.isSameColor(tgCard.getSuit());
		}

		// 如果tgCard是王,则本方只有是不同颜色的将(J/Q/K)或者士(A/2)才能够克制
		if (tgCard.isBlackJoker() || tgCard.isRedJoker()) {
			if (this.point >= 3 && this.point <= 10) {
				return false;
			}

			return !suit.isSameColor(tgCard.getSuit());
		}

		// 如果tgCard有技能"空城",那么相克关系失效,只有同花色大过该牌点数的牌才能克制
		if (tgCard.hasSkill(SKILL_EMPTY_CITY)) {
			if (this.getSuit() != tgCard.getSuit()) {
				return false;
			}

			return this.point > tgCard.getPoint();
		}

		// 如果本方有技能"鼓舞", 那么就可以攻击同颜色的牌(当然不包括王在内)
		if (this.hasSkill(Card.SKILL_CHEER_UP)) {
			if (this.suit.isSameColor(tgCard.getSuit()) && (this.suit != tgCard.getSuit())) {
				return true;
			} else if (this.point > tgCard.getPoint()) {
				return true;
			}
		}

		// 如果双方都是普通牌, 如果己方的花色克制tgCard的花色, 则返回true
		if (this.suit.restraintTo(tgCard.getSuit())) {
			return true;
		}

		// 如果花色相同,己方的点数大于tgCard的点数,则返回true
		if (this.suit == tgCard.getSuit()) {
			return this.point > tgCard.getPoint();
		}

		// 否则无法克制住对方,返回false
		return false;
	}

	@Override
	public int compareTo(ICard tgCard) {

		if (this.canBeat(tgCard) && !tgCard.canBeat(this)) {
			return 1;
		}

		if (!this.canBeat(tgCard) && tgCard.canBeat(this)) {
			return -1;
		}

		if (this.canBeat(tgCard) && tgCard.canBeat(this)) {
			return this.getPoint() - tgCard.getPoint();
		}

		if (!this.canBeat(tgCard) && !tgCard.canBeat(this)) {
			return 0;
		}

		return 0;
	}

}
